//
//  FiFoBuffer.cpp
//  sad
//
//  Created by Christopher Kemsley on 4/6/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#include "FiFoBuffer.hpp"

using namespace FiFo ;




Buffer :: Buffer	( sc_module_name const & inName , Length inCapacity , SCInterval const & inRWDelay )
:	sc_channel	( inName )
,	mData		()
,	mCapacity	( inCapacity )
,	mWasWritten	()
,	mWasRead	()
,	mRWDelay	(inRWDelay)
,	mTotalDataWritten ( std::string((char const*)inName)+".totalDataWritten" , "Words" )
	{
	
	}
Buffer :: ~Buffer () { }



void		Buffer :: write	( Word const & inValue )
	{
	if ( mData.size() > mCapacity )
		ThrowException ( "FiFo::Buffer" , "Buffer's data size is greater than the capacity" , __FILE__,__LINE__ ) ;
	
	while ( mData.size() == mCapacity )
		wait ( mWasRead ) ;
	
	wait ( mRWDelay ) ;
	
	mTotalDataWritten += 1 ;
	
	mData . push_back ( inValue ) ;
	
	mWasWritten.notify ( 0 , kSCIntervalSeconds ) ;
	}
Length		Buffer :: availableCapacity () const
	{
	return mCapacity - mData.size() ;
	}
Word const	Buffer :: read	()
	{
	if ( mData.size() > mCapacity )
		ThrowException ( "FiFo::Buffer" , "Buffer's data size is greater than the capacity" , __FILE__,__LINE__ ) ;
	
	while ( mData.size() == 0 )
		wait ( mWasWritten ) ;
	
	wait ( mRWDelay ) ;
	
	Word w = mData.front() ;
	mData.pop_front() ;
	
	mWasRead.notify ( 0 , kSCIntervalSeconds ) ;
	
	return w ;
	}
Length		Buffer :: availableLength () const
	{
	return mData.size() ;
	}



sc_event const&	Buffer :: wasWrittenEvent () const
	{
	return mWasWritten ;
	}
sc_event const&	Buffer :: wasReadEvent () const
	{
	return mWasRead ;
	}



